import 'package:flame/components.dart';
import 'package:flame/effects.dart';
import 'package:flame/events.dart';
import 'package:flame/extensions.dart';
import 'package:flutter/material.dart';
import 'package:flutter_flame/config/AssetsName.dart';
import 'package:flutter_flame/component/SpriteEntity.dart';
import 'package:flutter_flame/worlds/game/audio/SoundManager.dart';
import '../../../../bloc/game_bloc/GameEvent.dart';
import '../../GameWorld.dart';
import '../../state/SeedSelectionState.dart';
import '../../model/SeedModel.dart';
import '../DragShadow.dart';
import '../LawnCell.dart';
import '../PlantSeedCard.dart';
import 'SeedChooserBank.dart';
import 'StartButtonBackground.dart';
import '../TextCostSunlight.dart';

class SeedPacket extends SpriteEntity
    with TapCallbacks, HasWorldReference<GameWorld>, DragCallbacks {
  static const double _tileSize = 60.0;
  int i; // 行
  int j; // 列
  double startX; // 左边开始距离
  double startY; // 顶部开始
  double gap; // 间距
  int index; // 第几个植物
  bool showShadow; // 是否显示阴影
  bool isSeedBackground; // 只用作背景
  bool enableClickable = true; // 是否点击（防止过多移动效果）
  double moveEffectDuration = 0.2;
  StartButtonBackground? startBtnBg;
  final SeedSelectionState state; // 选择植物种子的状态
  late RectangleComponent shadowRectangle; // 阴影矩形
  late RectangleComponent opacityShadowRectangle; // 透明度矩形
  SeedModel get seedModel => state.seeds[index]; // 当前植物数据类

  /// 以下移植部分（拖动种植）
  late final Sprite preSetSprite; // 待种植植物
  late bool enablePlant; // 能否种植
  late double _coldTimeRemaining = 0; // 种植冷却剩余时间
  late final RectangleComponent coldRectangle; // 冷却矩形
  late final Paint _coolDownPaint = Paint()
    ..color = Colors.black.withValues(alpha: 0.6); // 冷却
  late final Timer _coolDownTimer = Timer(
    0.1,
    repeat: true,
    onTick: _handleCoolDownTick,
    autoStart: false,
  ); // 冷却倒计时

  SeedPacket({
    required this.i,
    required this.j,
    required this.startX,
    required this.startY,
    required this.gap,
    required this.index,
    required this.state,
    this.startBtnBg,
    this.isSeedBackground = false,
    this.showShadow = false,
  }) : super(AssetsName.spriteSeedChooserSeedPacketLarger) {
    enablePlant = true;
    _coldTimeRemaining = 0;
  }

  static final _paint = Paint()..color = Colors.black.withValues(alpha: 0.6);
  static final _paintOpacity = Paint()
    ..color = Colors.black.withValues(alpha: 0);

  EffectController _effectController([double? duration]) => EffectController(
        duration: duration ?? moveEffectDuration,
        curve: Curves.easeInOut,
      );

  @override
  Future<void> onLoad() async {
    await super.onLoad();
    preSetSprite = await Sprite.load(seedModel.image);
    setSize(_tileSize);
    final radio = sprite!.image.width / sprite!.image.height;
    _initRectangles(radio);
    _initPosition(radio);
    _addUIComponents();
    if (showShadow) add(shadowRectangle);
  }

  @override
  void update(double dt) {
    super.update(dt);
    if (_coldTimeRemaining >= 0) {
      _coolDownTimer.update(dt);
    }
  }

  @override
  void render(Canvas canvas) {
    super.render(canvas);
    if (seedModel.seedPacketState != SeedPacketState.draggable) return;
    // 绘制阴影
    if (world.bloc.state.sunlight < seedModel.costSunlight || !enablePlant) {
      if (!showShadow) {
        add(shadowRectangle);
        showShadow = true;
      }
    } else {
      if (showShadow) {
        remove(shadowRectangle);
        showShadow = false;
      }
    }
    // 绘制冷却
    if (_coldTimeRemaining >= 0) {
      final coolDownHeight = size.y * (_coldTimeRemaining / seedModel.coldTime);
      coldRectangle.height = coolDownHeight;
    }
  }

  @override
  void onDragStart(DragStartEvent event) {
    if (seedModel.seedPacketState != SeedPacketState.draggable) return;
    if (enablePlant && world.bloc.state.sunlight >= seedModel.costSunlight) {
      SoundManager().playChoosePlant();
      world.bloc.add(UpdateSelectedPlant(seedModel: seedModel));
      world.plantDragShadow = DragShadow(
        preSetSprite,
        setSize: seedModel.dragShadowSize,
      );
      // 创建拖动阴影
      world.plantDragShadow!.position =
          position + (seedModel.dragShadowOffset ?? Vector2.zero());
      world.add(world.plantDragShadow!);
    }
    super.onDragStart(event);
  }

  @override
  void onDragUpdate(DragUpdateEvent event) {
    if (seedModel.seedPacketState != SeedPacketState.draggable) return;
    world.plantDragShadow?.position += event.localDelta;
    //  更新植物的虚影
    final plantCenter = getPlantCenter();
    for (final lawnCell in world.lawnCells) {
      lawnCell.hidePlantShadow();
    }
    LawnCell? lawnCell = world.findLawnCellFromPosition(plantCenter);
    lawnCell?.showPlantShadow();
    super.onDragUpdate(event);
  }

  @override
  void onDragEnd(DragEndEvent event) {
    if (seedModel.seedPacketState != SeedPacketState.draggable) return;
    final plantCenter = getPlantCenter();
    // 查找放置的草坪格子
    LawnCell? lawnCell = world.findLawnCellFromPosition(plantCenter);
    if (lawnCell != null) {
      world.tryPlacePlant(lawnCell, this);
    }
    lawnCell?.hidePlantShadow();
    // 清理拖动状态
    world.plantDragShadow?.removeFromParent();
    world.plantDragShadow = null;
    world.bloc.add(UpdateSelectedPlant());
    super.onDragEnd(event);
  }

  @override
  void onTapDown(TapDownEvent event) {
    operateSelectorMenu();
    super.onTapDown(event);
  }

  // 开始冷却
  void startCoolDown() {
    enablePlant = false;
    _coldTimeRemaining = seedModel.coldTime;
    _coolDownTimer.start();
  }

  void _handleCoolDownTick() {
    _coldTimeRemaining -= 0.1;
    if (_coldTimeRemaining <= 0) {
      _coldTimeRemaining = 0;
      enablePlant = true;
      _coolDownTimer.stop();
    }
  }

  void _initRectangles(double radio) {
    shadowRectangle = RectangleComponent(
      position: Vector2.zero(),
      size: Vector2(_tileSize, _tileSize / radio),
      paint: _paint,
    );
    coldRectangle = RectangleComponent(
      position: Vector2.zero(),
      size: Vector2(_tileSize, _tileSize / radio),
      paint: _coolDownPaint,
    );
    opacityShadowRectangle = RectangleComponent(
      position: Vector2.zero(),
      size: Vector2(_tileSize, _tileSize / radio),
      paint: _paintOpacity,
    );
  }

  void _initPosition(double radio) {
    position = Vector2(
      startX + i * (_tileSize + gap),
      startY + (_tileSize / radio + gap * 2) * j,
    );
  }

  void _addUIComponents() {
    add(PlantSeedCard(seedModel: seedModel, onTap: operateSelectorMenu));
    add(TextCostSunlight(seedModel.costSunlight.toStringAsFixed(0)));
  }

  /// 选择植物种子
  void add2SelectorMenu() {
    enableClickable = false;
    seedModel.isSelected = true;
    final seedBankPos = state.seedBankPositions[state.preAddSelectorIndex];
    state.preAddSelectorIndex++;
    removeWhere((e) => e is MoveToEffect); // 移掉之前的移动效果
    SoundManager().choosePlantSeed(); // 选择种子
    add(
      MoveToEffect(
        seedBankPos,
        _effectController(),
        onComplete: () {
          state.selectedSeeds.add(this);
          if (state.selectedSeeds.length == state.maxSeedsLength) {
            startBtnBg?.setEnable();
          }
          enableClickable = true;
        },
      ),
    );
    // 选到最大数量后禁止再选
    if (state.preAddSelectorIndex == state.seedBankPositions.length) {
      final seedChooserBank = parent as SeedChooserBank;
      seedChooserBank.children.whereType<SeedPacket>().forEach(
            (e) => e.disableBeChoose(),
          );
    }
  }

  /// 移除种子
  void removeSelectorMenu() {
    enableClickable = false;
    seedModel.isSelected = false;
    state.preAddSelectorIndex--;
    removeWhere((e) => e is MoveToEffect);
    add(
      MoveToEffect(
        seedModel.initPosition!,
        _effectController(),
        onComplete: () {
          state.selectedSeeds.removeWhere((e) => e == this);
          enableClickable = true;
          startBtnBg?.setDisabled();
        },
      ),
    );
    // 开放选择
    final seedChooserBank = parent as SeedChooserBank;
    seedChooserBank.children
        .whereType<SeedPacket>()
        .where((e) => !e.seedModel.isSelected && !e.isSeedBackground)
        .forEach((e) => e.enableBeChoose());
  }

  /// 选择、取消选择种子
  void operateSelectorMenu() {
    if (seedModel.seedPacketState != SeedPacketState.selectable) return;
    if (!enableClickable || showShadow) return;
    if (seedModel.isSelected) {
      removeSelectorMenu();
      shuffleSelectorMenu();
    } else {
      add2SelectorMenu();
    }
  }

  /// 重排选择的植物的种子
  void shuffleSelectorMenu() {
    int index = 0;
    for (final item in state.selectedSeeds) {
      if (item.seedModel.isSelected) {
        item.add(
          MoveToEffect(
            state.seedBankPositions[index],
            _effectController(),
          ),
        );
        index++;
      }
    }
  }

  /// 禁止被选择
  void disableBeChoose() {
    if (!seedModel.isSelected) {
      showShadow = true;
      add(shadowRectangle);
    }
  }

  /// 开放选择
  void enableBeChoose() {
    if (!seedModel.isSelected && shadowRectangle.parent != null) {
      showShadow = false;
      remove(shadowRectangle);
    }
  }

  /// 可选择的按钮转为可拖动的按钮
  void selectableTransformDraggableMenu() {
    seedModel.seedPacketState = SeedPacketState.disable; // 移动时禁止操作
    if (seedModel.isSelected) {
      add(opacityShadowRectangle); // 变暗
      opacityShadowRectangle.add(
        OpacityEffect.to(
          0.1,
          EffectController(duration: 3, curve: Curves.easeInOut),
          onComplete: () {
            add(coldRectangle);
            seedModel.seedPacketState = SeedPacketState.draggable; // 转为可拖动的种子卡片
            remove(opacityShadowRectangle);
          },
        ),
      );
    }
  }

  Vector2 getPlantCenter() {
    final shadowPosition = world.plantDragShadow!.position;
    final shadowSize = world.plantDragShadow!.size;
    final plantCenter = Vector2(
      shadowPosition.x + shadowSize.x / 2,
      shadowPosition.y + shadowSize.y / 2,
    );
    return plantCenter;
  }
}
